//
//  NSDictionary+SafeNil.m
//  DK_TestApp
//
//  Created by DK on 2017/4/19.
//  Copyright © 2017年 ChunYu. All rights reserved.
//

#import "NSDictionary+SafeNil.h"
#import "JRSwizzle.h"

@implementation NSDictionary (SafeNil)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSError *error, *error2;
        [self jr_swizzleMethod:@selector(initWithObjects:forKeys:count:) withMethod:@selector(dk_initWithObjects:forKeys:count:) error:&error];
        [self jr_swizzleClassMethod:@selector(dictionaryWithObjects:forKeys:count:) withClassMethod:@selector(dk_dictionaryWithObjects:forKeys:count:) error:&error2];
    });
    
}

+ (instancetype)dk_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key||!obj) {
            continue;
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self dk_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}

- (instancetype)dk_initWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key||!obj) {
            continue;
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self dk_initWithObjects:safeObjects forKeys:safeKeys count:j];
}

@end

@implementation NSMutableDictionary (SafeNil)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSError *error, *error2;
        Class class = NSClassFromString(@"__NSDictionaryM");
        [class jr_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(dk_setObject:forKey:)error:&error];
        
        [class jr_swizzleMethod:@selector(setObject:forKeyedSubscript:) withMethod:@selector(dk_setObject:forKeyedSubscript:)error:&error2];
    });
}

- (void)dk_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
    if (!aKey||!anObject) {
        return;
    }
    [self dk_setObject:anObject forKey:aKey];
}

- (void)dk_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
    if (!key||!obj) {
        return;
    }
    [self dk_setObject:obj forKeyedSubscript:key];
}

@end

@implementation NSNull (SafeNil)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSError *error, *error2;
        [self jr_swizzleMethod:@selector(methodSignatureForSelector:) withMethod:@selector(dk_methodSignatureForSelector:)error:&error];
        [self jr_swizzleMethod:@selector(forwardInvocation:) withMethod:@selector(dk_forwardInvocation:)error:&error2];
    });
}

- (NSMethodSignature *)dk_methodSignatureForSelector:(SEL)aSelector {
    
    NSMethodSignature *sig = [self dk_methodSignatureForSelector:aSelector];
    // 能实现方法则返回该签名
    if (sig) {  return sig; }
    // 方法重签名为空指针
    return [NSMethodSignature signatureWithObjCTypes:@encode(void)];
}

- (void)dk_forwardInvocation:(NSInvocation *)anInvocation {
    
    //-->如果转发来的是空指针，那么returnLength长度为0,anInvocation-> void
    NSUInteger methodReturnLength = [[anInvocation methodSignature] methodReturnLength];
    if (!methodReturnLength) {
        return;
    }
    
    // 不是空指针，则建立一个大小为returnLength的数组，并进行初始化为0
    char bf[methodReturnLength];
    // memset快速初始化数组宏定义，C方法
    memset(bf, 0, methodReturnLength);
    // 返回一个都为0的内存地址
    [anInvocation setReturnValue:bf];
}

@end
